package cz.muni.fi.pa165.musiclibrary.impl.database.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.springframework.beans.factory.annotation.Required;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

import cz.muni.fi.pa165.musiclibrary.impl.database.entity.IArtist;
import cz.muni.fi.pa165.musiclibrary.impl.database.entity.Artist;

/**
 *
 * @author Radoslav Stefanik 2012-10-13T10:07:11+0200
 */
@Repository
public class ArtistDAO extends AbstractDAO implements IArtistDAO {

    /**
     * Factory for creating {@link EntityManager}.
     */
    private EntityManager entityManager;

    /**
     * Injects {@link EntityManager} instance.
     */
    @PersistenceContext
    @Required
    @Override
    public void setEntityManager(final EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    @Override
    public void create(final IArtist artist) throws DataAccessException {
        Validate.isTrue(artist != null, "artist should not be null");
        Validate.isTrue(artist.getIdArtist() == null, "Artist id should be null");
        Validate.isTrue(artist.getName() != null, "Artist name should not be null");

        this.entityManager.persist(artist);
    }

    @Override
    public void update(final IArtist artist) throws DataAccessException {
        Validate.isTrue(artist != null, "artist should not be null");
        Validate.isTrue(artist.getName() != null, "Artist name should not be null");
        Validate.isTrue(artist.getIdArtist() != null, "Artist id should not be null");

        final Query update = this.entityManager.createQuery("UPDATE Artist a SET a.name = :name, a.description = :description WHERE a.idArtist = :idArtist");
        update.setParameter("name", artist.getName())//
                .setParameter("description", artist.getDescription())//
                .setParameter("idArtist", artist.getIdArtist());
        update.executeUpdate();  
    }

    @Override
    public void delete(final IArtist artist) throws DataAccessException {
        Validate.isTrue(artist != null, "artist should not be null");
        Validate.isTrue(artist.getName() != null, "Artist name should not be null");
        Validate.isTrue(artist.getIdArtist() != null, "Artist id should not be null");

        final Query update = this.entityManager.createQuery("DELETE FROM Artist a WHERE a.idArtist = :idArtist");
        update.setParameter("idArtist", artist.getIdArtist());
        update.executeUpdate();
    }

    @Override
    public IArtist getById(final Long idArtist) throws DataAccessException {
        Validate.isTrue(idArtist != null, "Artist id should not be null");

        final Artist artist = this.entityManager.find(Artist.class, idArtist);
        return artist;
    }

    @Override
    public List<IArtist> getAll() throws DataAccessException {
        List<IArtist> list = this.entityManager.createQuery("SELECT a FROM Artist a").getResultList();
        return list;
    }

    @Override
    public List<IArtist> getByName(final String name) throws DataAccessException {
        Validate.isTrue(name != null, "Artist name should not be null");
        Validate.isTrue(!StringUtils.isBlank(name), "Artist name should not be blank");

        String query = "SELECT a FROM Artist a WHERE LOWER(a.name) like '%" + name.toLowerCase() + "%'";
        List<IArtist> list = this.entityManager.createQuery(query).getResultList();
        return list;
    }
    
}